package com.example.gss.ServiceImpl;

import com.example.gss.entity.CourseScore;
import com.example.gss.mapper.CourseScoreMapper;
import com.example.gss.Service.CourseScoreService;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * 学业成绩服务实现类
 */
@Service
@Transactional
public class CourseScoreServiceImpl implements CourseScoreService {

    @Autowired
    private CourseScoreMapper scoreMapper;

    @Override
    public CourseScore addScore(CourseScore score) {
        scoreMapper.insert(score);
        return score;
    }

    @Override
    public CourseScore getScoreById(String id) {
        return scoreMapper.selectById(id);
    }

    @Override
    public List<CourseScore> getAllScores() {
        return scoreMapper.selectAll();
    }

    @Override
    public List<CourseScore> getScoresByStudentId(String studentId) {
        return scoreMapper.selectByStudentId(studentId);
    }

    @Override
    public List<CourseScore> getScoresByCourseId(String courseId) {
        return scoreMapper.selectByCourseId(courseId);
    }

    @Override
    public CourseScore updateScore(String id, CourseScore score) {
        CourseScore existingScore = scoreMapper.selectById(id);
        if (existingScore != null) {
            score.setScoreId(id);
            scoreMapper.update(score);
            return score;
        }
        return null;
    }

    @Override
    public void deleteScore(String id) {
        scoreMapper.deleteById(id);
    }

    @Override
    public BigDecimal calculateAverageScoreByStudentId(String studentId) {
        return scoreMapper.calculateAverageScoreByStudentId(studentId);
    }

    @Override
    public BigDecimal calculateDegreeCourseAverageScoreByStudentId(String studentId) {
        return scoreMapper.calculateDegreeCourseAverageScoreByStudentId(studentId);
    }

    @Override
    public Map<String, Object> batchImportScores(MultipartFile file) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        int successCount = 0;
        
        try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
            Sheet sheet = workbook.getSheetAt(0);
            
            // 跳过标题行
            for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                Row row = sheet.getRow(i);
                if (row == null) continue;
                
                try {
                    CourseScore score = new CourseScore();
                    
                    // 读取学号
                    Cell studentIdCell = row.getCell(0);
                    if (studentIdCell != null) {
                        score.setStudentId(getCellValueAsString(studentIdCell));
                    } else {
                        errors.add("第" + (i + 1) + "行：学号不能为空");
                        continue;
                    }
                    
                    // 读取课程编号
                    Cell courseIdCell = row.getCell(1);
                    if (courseIdCell != null) {
                        score.setCourseId(getCellValueAsString(courseIdCell));
                    } else {
                        errors.add("第" + (i + 1) + "行：课程编号不能为空");
                        continue;
                    }
                    
                    // 读取课程名称
                    Cell courseNameCell = row.getCell(2);
                    if (courseNameCell != null) {
                        score.setCourseName(getCellValueAsString(courseNameCell));
                    } else {
                        errors.add("第" + (i + 1) + "行：课程名称不能为空");
                        continue;
                    }
                    
                    // 读取成绩
                    Cell scoreCell = row.getCell(3);
                    if (scoreCell != null) {
                        double scoreValue = getCellValueAsDouble(scoreCell);
                        if (scoreValue >= 0 && scoreValue <= 100) {
                            score.setScore(BigDecimal.valueOf(scoreValue));
                        } else {
                            errors.add("第" + (i + 1) + "行：成绩必须在0-100之间");
                            continue;
                        }
                    } else {
                        errors.add("第" + (i + 1) + "行：成绩不能为空");
                        continue;
                    }
                    
                    // 读取是否学位课程
                    Cell degreeCourseCell = row.getCell(4);
                    if (degreeCourseCell != null) {
                        String degreeCourseValue = getCellValueAsString(degreeCourseCell);
                        score.setIsDegreeCourse("是".equals(degreeCourseValue) || "true".equalsIgnoreCase(degreeCourseValue));
                    } else {
                        score.setIsDegreeCourse(false);
                    }
                    
                    // 生成成绩ID
                    score.setScoreId(String.valueOf(System.currentTimeMillis() + i));
                    
                    // 保存到数据库
                    scoreMapper.insert(score);
                    successCount++;
                    
                } catch (Exception e) {
                    errors.add("第" + (i + 1) + "行：处理失败 - " + e.getMessage());
                }
            }
            
        } catch (IOException e) {
            errors.add("文件读取失败：" + e.getMessage());
        }
        
        result.put("success", errors.isEmpty());
        result.put("successCount", successCount);
        result.put("errorCount", errors.size());
        result.put("errors", errors);
        result.put("message", String.format("成功导入%d条记录，失败%d条记录", successCount, errors.size()));
        
        return result;
    }
    
    private String getCellValueAsString(Cell cell) {
        if (cell == null) return "";
        
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return String.valueOf((int) cell.getNumericCellValue());
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            default:
                return "";
        }
    }
    
    private double getCellValueAsDouble(Cell cell) {
        if (cell == null) return 0.0;
        
        switch (cell.getCellType()) {
            case NUMERIC:
                return cell.getNumericCellValue();
            case STRING:
                try {
                    return Double.parseDouble(cell.getStringCellValue());
                } catch (NumberFormatException e) {
                    return 0.0;
                }
            default:
                return 0.0;
        }
    }
}